﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProjTemp.Common.Logging;
using System.Windows;
using ProjTemp.Common;
using System.Reflection;
using Csla;
using System.Windows.Threading;
using ProjTemp.Desktop.Common.MessageBox;
using ProjTemp.Desktop.Common.ResourceManagement;
using MahApps.Metro;

namespace ProjTemp.Desktop.Common.App
{
    public class AppBase : Application
    {
        private ILogger _logger;

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            //Log
            this._logger = new Logger();
            this._logger.LogType = typeof(AppBase);
            this._logger.Info(GlobalConst.ProgramStarted);
            //Global Exception
            //this.InitializeResourceManager();
            this.CaptureUnhandledException();
            //Config
            this.InitializeConfiguration();
            //Theme
            this.ChangeTheme();

            //Start up
            this.StartUp();
        }

        protected virtual void InitializeConfiguration()
        {
            this._logger.InfoFormat(GlobalConst.MethodEntered, MethodBase.GetCurrentMethod().Name);

            ApplicationContext.LocalContext[StyleConst.DefaultTheme] = "Dark";
            ApplicationContext.LocalContext[StyleConst.DefaultAccent] = "Red";
        }

        public virtual void ChangeTheme()
        {
            Theme theme = Theme.Light;
            Accent accent = ThemeManager.DefaultAccents.First(x => x.Name == "Green");
            //Theme
            Theme configTheme;
            var defaultTheme = ApplicationContext.LocalContext[StyleConst.DefaultTheme] as string;
            if (!string.IsNullOrEmpty(defaultTheme) && Enum.TryParse<Theme>(defaultTheme, out configTheme))
                theme = configTheme;
            var defaultAccent = ApplicationContext.LocalContext[StyleConst.DefaultAccent] as string;
            if (!string.IsNullOrEmpty(defaultAccent) && ThemeManager.DefaultAccents.FirstOrDefault(x => x.Name == defaultAccent) != null)
                accent = ThemeManager.DefaultAccents.FirstOrDefault(x => x.Name == defaultAccent);
            ThemeManager.ChangeTheme(this, accent, theme);
        }

        protected virtual void CaptureUnhandledException()
        {
            // UI thread exceptions
            this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
            // Background thread exceptions
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        }

        protected virtual void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            HandleException(e.Exception);
            e.Handled = true;
        }

        protected virtual void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            var ex = e.ExceptionObject as Exception;
            if (ex != null)
                HandleException(ex);
        }

        protected virtual void HandleException(Exception ex)
        {
            try
            {
                _logger.ErrorFormat(GlobalConst.UnhandledException, ex);
                MessageBoxHelper.Error(ex.Message);
            }
            catch { }
        }

        protected virtual void InitializeResourceManager()
        {
            try
            {
                var resourceManager = new ResourceManager(new Logger()) as IResourceManage;
                resourceManager.AddResourceDictionary(new ResourceDictionary() { Source = new Uri("pack://application:,,,/Mysoft.ServerMonitoring.OMKit.Resource;component/Lang/Error.en-US.xaml") }, DesktopConst.LanguageResourceSubject, "en-US");
                resourceManager.AddResourceDictionary(new ResourceDictionary() { Source = new Uri("pack://application:,,,/Mysoft.ServerMonitoring.OMKit.Resource;component/Lang/Message.en-US.xaml") }, DesktopConst.LanguageResourceSubject, "en-US");
                resourceManager.AddResourceDictionary(new ResourceDictionary() { Source = new Uri("pack://application:,,,/Mysoft.ServerMonitoring.OMKit.Resource;component/Lang/Resource.en-US.xaml") }, DesktopConst.LanguageResourceSubject, "en-US");
                resourceManager.AddResourceDictionary(new ResourceDictionary() { Source = new Uri("pack://application:,,,/Mysoft.ServerMonitoring.OMKit.Resource;component/Lang/Validation.en-US.xaml") }, DesktopConst.LanguageResourceSubject, "en-US");
                resourceManager.AddResourceDictionary(new ResourceDictionary() { Source = new Uri("pack://application:,,,/Mysoft.ServerMonitoring.OMKit.Resource;component/Lang/Error.zh-CN.xaml") }, DesktopConst.LanguageResourceSubject, "zh-CN");
                resourceManager.AddResourceDictionary(new ResourceDictionary() { Source = new Uri("pack://application:,,,/Mysoft.ServerMonitoring.OMKit.Resource;component/Lang/Message.zh-CN.xaml") }, DesktopConst.LanguageResourceSubject, "zh-CN");
                resourceManager.AddResourceDictionary(new ResourceDictionary() { Source = new Uri("pack://application:,,,/Mysoft.ServerMonitoring.OMKit.Resource;component/Lang/Resource.zh-CN.xaml") }, DesktopConst.LanguageResourceSubject, "zh-CN");
                resourceManager.AddResourceDictionary(new ResourceDictionary() { Source = new Uri("pack://application:,,,/Mysoft.ServerMonitoring.OMKit.Resource;component/Lang/Validation.zh-CN.xaml") }, DesktopConst.LanguageResourceSubject, "zh-CN");
                resourceManager.SetDefaultAspect(DesktopConst.LanguageResourceSubject, "zh-CN");
                resourceManager.ApplyToResourceDictionary(this.Resources);
            }
            catch(Exception ex)
            {
                _logger.ErrorFormat(GlobalConst.ExceptionOccurs, MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        protected virtual void StartUp()
        {

        }
    }
}
